package com.todo.admin.config.filter;

import com.todo.admin.common.exception.ApiException;
import com.todo.admin.common.exception.error.ErrorCode;
import com.todo.admin.common.base.RoleInfo;
import com.todo.admin.common.base.SystemLoginUser;
import com.todo.admin.entity.enums.common.UserStatusEnum;
import com.todo.admin.service.TokenService;
import com.todo.admin.system.user.UserApplicationService;
import com.todo.admin.system.user.db.SysUserEntity;
import com.todo.admin.system.user.db.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * @author azhebuxing
 * @date 2025/2/22 21:28
 * @description
 */
@Slf4j
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    @Resource
    private TokenService tokenService;

    @Resource
    private UserApplicationService userApplicationService;

    @Resource
    private SysUserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        // 从请求头中获取Token
        String token = extractToken(request);

        if (token != null) {
            // 根据Token加载用户信息
            UserDetails userDetails = loadUserDetailsByToken(token);

            if (userDetails != null) {
                // 创建Authentication对象
                Authentication authentication = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());

                // 将Authentication对象放入SecurityContextHolder
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }

        // 继续过滤器链
        filterChain.doFilter(request, response);
    }

    private String extractToken(HttpServletRequest request) {
        // 从请求头中获取Token，例如从Authorization头中获取
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }

    private UserDetails loadUserDetailsByToken(String token) {
        String username = tokenService.getUserName(token);
        if (username != null) {
            SysUserEntity userEntity = userService.getUserByUserName(username);
            if (userEntity == null) {
                log.info("TokenAuthenticationFilter 解析token后获取数据：{} 不存在.", username);
                throw new ApiException(ErrorCode.Business.USER_NON_EXIST, username);
            }
            if (!Objects.equals(UserStatusEnum.NORMAL.getValue(), userEntity.getStatus())) {
                log.info("TokenAuthenticationFilter 解析token后获取数据：{} 已被停用.", username);
                throw new ApiException(ErrorCode.Business.USER_IS_DISABLE, username);
            }
            RoleInfo roleInfo = userApplicationService.getRoleInfo(userEntity.getRoleId(), userEntity.getIsAdmin());

            SystemLoginUser loginUser = new SystemLoginUser(userEntity.getUserId(), userEntity.getIsAdmin(), userEntity.getUsername(),
                    userEntity.getPassword(), roleInfo, userEntity.getDeptId());
            return loginUser;
        }
        return null;
    }
}
